Appendix D — Assignment D

Instructions

  1. You may talk to a friend, discuss the questions and potential directions for solving them. However, you need to write your own solutions and code separately, and not as a group activity.

  2. Do not write your name on the assignment.

  3. Insert Code cells in the template provided to write solutions for the assignment. Do not open a new notebook, and work from scratch.

  4. Write your code in the Code cells, and text in the Markdown cells of the Jupyter notebook. Ensure that the solution is written neatly enough to understand and grade.

  5. Use Quarto to print the .ipynb file as HTML. You will need to open the command prompt, navigate to the directory containing the file, and use the command: quarto render filename.ipynb --to html. Submit the HTML file.

  6. There are 5 points for clealiness and organization. The breakdow is as follows:

  • Must be an HTML file rendered using Quarto (1.5 pts).

  • There aren’t excessively long outputs of extraneous information (e.g. no printouts of unnecessary results without good reason, there aren’t long printouts of which iteration a loop is on, there aren’t long sections of commented-out code, etc.). There is no piece of unnecessary / redundant code, and no unnecessary / redundant text (1 pt)

  • The code follows the python style guide for naming variables, spaces, indentation, etc. (1 pt)

  • The code should be commented and clearly written with intuitive variable names. For example, use variable names such as number_input, factor, hours, instead of a,b, xyz, etc. For repetitive code chunks, either copy the comments or just leave a comment mentioning that the comment is the same as in the previous occurrece of the code chunk (1.5 pts)

  1. The assignment is worth 100 points, and is due on 13th Feb 2024 at 11:59 pm.

D.1 SMS store manager

Create a new class, named as SMS_store_manager. This class will be used to store and manage SMSs of a person’s cellphone. An object of this class, say my_inbox, will be initialized with a list of existing messages. The class attribute messages will store the existing messages during instantiation:

Code
my_inbox(existing_messages)

Each message in the list will be represented as a dictionary. A sample message is shown below:

Code
{'has_been_viewed':True, 'from_number':9348593356, 'time_arrived':'19:50', 'date':'2022-10-27','text_of_SMS':'Hi, how about lunch at 11?'}

The class should provide these methods:

Code
my_inbox.add_new_arrival(from_number, time_arrived, date, text_of_SMS)
#Makes new SMS dictionary, inserts it after other messages
#in the store, i.e, in the list of messages. When creating this message, its
#'has_been_viewed' status is set False.

my_inbox.message_count()
#Returns the number of sms messages in my_inbox

my_inbox.get_unread_messages()
#Returns unread messages, i.e., messages with 'has_been_viewed' status as False
#Also changes the status of 'has_been_viewed' to True for all messages returned
#While returning unread messages, the 'has_been_viewed' status must not be returned

my_inbox.delete(i)     # Delete the message at index i
my_inbox.clear()       # Delete all messages from inbox

Once you define the class, instantiate an object of this class, and call it alice_messages. Initialize the object with the existing messages below.

Code
existing_messages = [{'has_been_viewed':False, 'from_number':8769038451, 'time':'09:30','date':'2022-10-27','text_of_SMS':'Hi, how about lunch at 11?'},
                        {'has_been_viewed':False, 'from_number':9579038373, 'time':'19:30','date':'2022-10-20', 'text_of_SMS':'Your order has arrived'},
                        {'has_been_viewed':True, 'from_number':8639568726, 'time':'10:30','date':'2022-09-30','text_of_SMS':'Card not present on American Express acc ending 54345 Sep 30 Amount $45.43 Merch: TOMATEFRESHKITCHEN.COM if unrecognized call # on Card'},
                        {'has_been_viewed':False, 'from_number':4567653456, 'time':'11:50','date':'2022-09-15','text_of_SMS':'Hi Brooke, we are confirming your Covid vaccine appointment on Thursday at 1900 hours'},
                        {'has_been_viewed':False, 'from_number':5646786643, 'time':'18:50','date':'2022-09-11','text_of_SMS':'Where is the party bro?'},
                        {'has_been_viewed':False, 'from_number':9845543492, 'time':'17:10','date':'2022-09-10','text_of_SMS':'Free trial of ScanApp for 7 days for clear scanned documents, cancel anytime, $10.99 per month after 7 days'},
                        {'has_been_viewed':True, 'from_number':8793450987, 'time':'13:20','date':'2022-08-31','text_of_SMS':'Hey Brooke, I have sent you my resume for feedback'},
                        {'has_been_viewed':True, 'from_number':874556445, 'time':'07:20','date':'2022-08-19','text_of_SMS':'Which route are we taking for the run today?'},
                        {'has_been_viewed':True, 'from_number':998456435, 'time':'07:20','date':'2022-07-31','text_of_SMS':'Reservation confirmed at the New York Plaza hotel for 2022-08-09 to 2022-09-14.'},
                        {'has_been_viewed':True, 'from_number':8769038451, 'time':'07:20','date':'2022-07-25','text_of_SMS':'Lets catchup sometime, it has been so long!'},
                        {'has_been_viewed':True, 'from_number':7739984533, 'time':'07:20','date':'2022-07-24','text_of_SMS':'Do you want to be rich today? Do you want to be your own boss? Check out beyourownboss.com. Register today for just $5!!!'},
                        {'has_been_viewed':True, 'from_number':3443498738, 'time':'07:20','date':'2022-07-22','text_of_SMS':'Want to lose weight? Get Dr. Oz magic pills @ozpills.com. Satisfaction guaranteed.'}]

Use the object alice_messages to:

D.1.1

Count the number of messages.

(2 points)

D.1.2

Print all the unread messages.

(6 points)

D.1.3

Add a new message below:

Code
from_number=8749373884;
time='07:25';
date='2022-10-29'
text_of_SMS='Hey, I want my bike back.'

(4 points)

D.1.4

Print all the unread messages again (Only the recently added message should show up).

(4 points)

D.1.5

Count the number of messages, clear the inbox, and then count the number of messages again.

(4 points)

D.2 Personalized SMS store manager

Inherit the class developed in the previous question to create a new class SMS_personalized_store_manager. This class will inherit all the methods of the class SMS_store_manager. However, it will have the following differences as compared to the parent class:

  1. Instantiation

    1. During instantiation, it will initialize two additional attributes - spam_words, and update_words, along with the messages attribute which stores existing messages. Use the lists below to initialize the attributes of the class.

    2. Each message will be tagged as spam, update, or personal as follows. If the message contains any word / phrase in the list spam_words, then it will be tagged as spam. If the message is not tagged as spam, and it contains any word / phrase in the list update_words, then it will be tagged as update. If the message has not been tagged as spam or update, then it will be tagged as personal. The tag will appear as an additional key-value pair in the dictionary of each message, where the key will be tag, and the value will be 'spam', 'update' or 'personal'. Words / phrases must be identified as spam / update irrespective of the case of the word. For e.g., if Be your own Boss is a spam phrase, then be your own boss is also a spam phrase.

A message after tagging may look like:

Code
{'has_been_viewed':True, 'from_number':9348593356, 'time_arrived':'19:50', 'date':'2022-10-27','text_of_SMS':'Hi, how about lunch at 11?', 'tag':'personal'}
Code
#Lists for initializing the attributes of the class
existing_messages = [{'has_been_viewed':False, 'from_number':8769038451, 'time':'09:30','date':'2022-10-27','text_of_SMS':'Hi, how about lunch at 11?'},
                        {'has_been_viewed':False, 'from_number':9579038373, 'time':'19:30','date':'2022-10-20', 'text_of_SMS':'Your order has arrived'},
                        {'has_been_viewed':True, 'from_number':8639568726, 'time':'10:30','date':'2022-09-30','text_of_SMS':'Card not present on American Express acc ending 54345 Sep 30 Amount $45.43 Merch: TOMATEFRESHKITCHEN.COM if unrecognized call # on Card'},
                        {'has_been_viewed':False, 'from_number':4567653456, 'time':'11:50','date':'2022-09-15','text_of_SMS':'Hi Brooke, we are confirming your Covid vaccine appointment on Thursday at 1900 hours'},
                        {'has_been_viewed':False, 'from_number':5646786643, 'time':'18:50','date':'2022-09-11','text_of_SMS':'Where is the party bro?'},
                        {'has_been_viewed':False, 'from_number':9845543492, 'time':'17:10','date':'2022-09-10','text_of_SMS':'Free trial of ScanApp for 7 days for clear scanned documents, cancel anytime, $10.99 per month after 7 days'},
                        {'has_been_viewed':True, 'from_number':8793450987, 'time':'13:20','date':'2022-08-31','text_of_SMS':'Hey Brooke, I have sent you my resume for feedback'},
                        {'has_been_viewed':True, 'from_number':874556445, 'time':'07:20','date':'2022-08-19','text_of_SMS':'Which route are we taking for the run today?'},
                        {'has_been_viewed':True, 'from_number':998456435, 'time':'07:20','date':'2022-07-31','text_of_SMS':'Reservation confirmed at the New York Plaza hotel for 2022-08-09 to 2022-09-14.'},
                        {'has_been_viewed':True, 'from_number':8769038451, 'time':'07:20','date':'2022-07-25','text_of_SMS':'Lets catchup sometime, it has been so long!'},
                        {'has_been_viewed':True, 'from_number':7739984533, 'time':'07:20','date':'2022-07-24','text_of_SMS':'Do you want to be rich today? Do you want to be your own boss? Check out beyourownboss.com. Register today for just $5, or book an appointment at 985-998-3452!!!'},
                        {'has_been_viewed':True, 'from_number':3443498738, 'time':'07:20','date':'2022-07-22','text_of_SMS':'Want to lose weight? Get Dr. Oz magic pills @ozpills.com. Satisfaction guaranteed.'}]
spam_words=['100% more', '100% free', '100% satisfied', 'Additional income', 'Be your own boss', 'Best price', 'Big bucks', 'Billion', 'Cash bonus', 'Cents on the dollar', 'Consolidate debt', 'Double your cash', 'Double your income', 'Earn extra cash', 'Earn money', 'Eliminate bad credit', 'Extra cash', 'Extra income', 'Expect to earn', 'Fast cash', 'Financial freedom', 'Free access', 'Free consultation', 'Free gift', 'Free hosting', 'Free info', 'Free investment', 'Free membership', 'Free money', 'Free preview', 'Free quote', 'Free trial', 'Full refund', 'Get out of debt', 'Get paid', 'Giveaway', 'Guaranteed', 'Increase sales', 'Increase traffic', 'Incredible deal', 'Lower rates', 'Lowest price', 'Make money', 'Million dollars', 'Miracle', 'Money back', 'Once in a lifetime', 'One time', 'Pennies a day', 'Potential earnings', 'Prize', 'Promise', 'Pure profit', 'Risk-free', 'Satisfaction guaranteed', 'Save big money', 'Save up to', 'Special promotion']
update_words = ['Your order', 'appointment', 'Reservation confirmed', 'Card Not Present', 'Payment confirmation', 'Your payment']
  1. The class will have two additional methods:

    1. get_unread_messages_by_category(): This method will return all the unread messages of a particular category, i.e, 'spam', 'update' or 'personal'. The method will accept the category as an argument. If no argument is specified by the user for the category, then all the unread messages must be displayed. Once unread messages are returned, they will be marked as read. While returning unread messages, the has_been_viewed status must be changed to True, but the status itself must not be returned.

    2. get_messages_by_category(): This method will return all the messages (both read or unread) of a particular category, i.e, 'spam', 'update' or 'personal'. The method will accept the category as an argument. If no argument is specified by the user for the category, then all the messages must be returned.

  2. The class will modify the method add_new_arrival(self,from_number, time, date, text_of_SMS) of the parent class to tag a new message as 'spam', 'update' or 'personal'.

Once you define the class, instantiate an object of this class with the lists existing_messages, spam_words and update_words, and call it ron_messages:

D.2.1

Add a new message below:

Code
from_number=8749373884;
time='07:25';
date='2022-10-29'
text_of_SMS='Hey, I want my bike back.'

(6 points)

D.2.2

Print all the unread messages tagged as personal. Use the method get_unread_messages_by_category().

(10 points)

D.2.3

Print all the unread messages tagged as update. Use the method get_unread_messages_by_category().

(10 points)

D.2.4

Print all the unread messages. Use the method get_unread_messages().

(10 points)

D.2.5

Print all the messages tagged as spam. Use the method get_messages_by_category().

(7 points)

D.2.6

Print all the messages tagged as update. Use the method get_messages_by_category().

(7 points)

D.3 Creating a new datatype - list of dictionaries

Read movie_data with the code below.

Code
import json
with open("movies.json", encoding="utf8") as file:
    movie_data=json.load(file)

Inherit the in-built python class list() to create a new class list_dict(). This class will be used for objects that are a list of dictionaries, where all the dictionaries in the list have the same keys. For example, if the first object of the list is a dictionary with keys a and b, then the second object of the list is also a dictionary with keys a and b and so on.

Add a method in this class, named as sort_by_dict_value() that sorts the dictionaries of the list based on the values of the desired key in the dictionaries. Sorting can be done in ascending or descending order depending on the user. The key to be used for sorting and the order (ascending / descending) will be parameters to the method sort_by_dict_value(). If the sorting order is unspecified, use ascending as default.

Instantiate an object of the class list_dict() with movie_data.

If the name of the object is mov, then the method sort_by_dict_value() may be called as: mov.sort_by_dict_value(movie_parameter, ascending = True)

where movie_parameter can be any key of the dictionaries, using the values of which the list of dictionaries has to be sorted. Ignore the movies for which movie_parameter has a missing value, i.e., its value is None.

D.3.1

Use the method sort_by_dict_value() to sort the list of dictionaries in increasing order of Production Budget. What is the name of the 45th movie in the sorted list of dictionaries?

D.3.2

Use the method sort_by_dict_value() to sort the list of dictionaries in decreasing order of Worldwide Gross. What is the name of the 2nd movie in the sorted list of dictionaries?

Hint: You may use the function rankdata from the stats module of the scipy library

(25 points)